/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.admin.client.components;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.admin.client.AdminComponentController;
import com.elf.gwt.admin.client.subcomponents.ConfigurationSubComponent;
import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.model.ConfigurationModel;
import com.elf.gwt.common.client.model.GroupModel;
import com.elf.gwt.common.client.model.ModuleModel;
import com.elf.gwt.common.client.subcomponent.CommonSubComponent;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;

/**
 *  
 */
public class ModuleComponent extends JSONServerComponent
{
	protected static final String Update = "Update";
	protected ConfigurationSubComponent subcomponent;
	protected List<ModuleModel> moduleModels;
	protected String selectedGroup = "";
	protected ModuleModel selectedModuleModel = null;
	protected boolean edit = false;
	protected String action = "";

	protected HorizontalPanel bodyPanel;
	protected Grid grid;

	/**
	 * Constructor
	 */
	public ModuleComponent(AdminComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix);
		moduleModels = new ArrayList<ModuleModel>();
		setupTimer();
	}
	public void additionalRequestParameters()
	{
		addRequestParameter(new RequestParameter("module_group", selectedGroup));
		if (action != null && action.length() > 0 && selectedModuleModel != null)
		{
			addRequestParameter(new RequestParameter("module_class", selectedModuleModel.getModuleClass()));
			
			if (action.equals("Update"))
			{
				boolean actualUpdate = false;
				List<ConfigurationModel> configurationModels = selectedModuleModel.getConfigurations();
				int sz = configurationModels.size();
				for (int i = 0; i < sz; i++)
				{
					ConfigurationModel configurationModel = configurationModels.get(i);
					Widget widget = subcomponent.getEditWidgets().get(i);
					String value = CommonUtils.getValue(widget);

					String currValue = configurationModel.getValue();
					if ((currValue == null && value == null) || (currValue != null && value != null && currValue.equals(value))) continue;
					actualUpdate = true;
					String key = configurationModel.getKey();
					addRequestParameter(new RequestParameter(key, value));
				}
				if (actualUpdate) 
					addRequestParameter(new RequestParameter("action", "Update"));
			}
			else
			{
				addRequestParameter(new RequestParameter("action", action));
			}
			action = "";
		}
	}

	protected void buildMetaModel(JSONObject jsonObject) throws Exception
	{
	}

	/**
	 * BuildData from JSONArray
	 * @param jsonArray
	 */
	protected void buildModel(JSONArray jsonArray) throws Exception
	{
		moduleModels.clear();
		super.buildModel(jsonArray);
	}

	protected void buildModel(JSONObject jsonObject) throws Exception
	{
		moduleModels.add(new ModuleModel(jsonObject));
	}

	public void buildFromModel() throws Exception
	{
		
		int sz = moduleModels.size();
		bodyPanel = new HorizontalPanel();

		if (sz > 0)
		{
			setSelectedGroup(moduleModels.get(0).getGroup());
			if (selectedModuleModel == null) selectedModuleModel = moduleModels.get(0);
			else {
				Iterator<ModuleModel> mmsIter = moduleModels.iterator();
				boolean match = false;
				while(mmsIter.hasNext()) {
					ModuleModel currModuleModel = mmsIter.next();
					if (currModuleModel.getCode() == selectedModuleModel.getCode())
					{
						match = true;
						break;
					}
				}
				if (!match) selectedModuleModel = moduleModels.get(0);
			}
		}

		int col = 5;
		grid = new Grid(sz+1, col);
		grid.addClickHandler(tableHandler);

		grid.setText(0, 0, "Module");
		grid.setText(0, 1, "Installed");
		grid.setText(0, 2, "Enabled");
		grid.setText(0, 3, "Sort Order");
		grid.setText(0, 4, "Action");

		for (int i = 0; i < sz; i++)
		{
			grid.getRowFormatter().addStyleName(i+1, "ComponentLink");
			int k = i % 2;
			String rowStyle = "Odd";
			if (k > 0) rowStyle = "Even";
			grid.getRowFormatter().addStyleName(i+1, rowStyle);
			ModuleModel moduleModel = moduleModels.get(i);
			List<ConfigurationModel> configurations = moduleModel.getConfigurations();
			boolean enabled = false;
			int sortOrder = 0;
			for (Iterator<ConfigurationModel> iter = configurations.iterator(); iter.hasNext(); )
			{
				ConfigurationModel configurationModel = iter.next();
				if (configurationModel.getKey().endsWith("_STATUS")) enabled = Boolean.parseBoolean(configurationModel.getValue());
				else if (configurationModel.getKey().endsWith("_SORT_ORDER")) sortOrder = Integer.parseInt(configurationModel.getValue());
			}
			grid.setText(i+1, 0, moduleModel.getCode());
			grid.setText(i+1, 1, String.valueOf(moduleModel.isInstalled()));
			grid.setText(i+1, 2, String.valueOf(enabled));
			grid.setText(i+1, 3, String.valueOf(sortOrder));
			if (selectedModuleModel.getCode().equals(moduleModel.getCode())) {
				selectedModuleModel = moduleModel;
				grid.setWidget(i+1, 4, new Image(getImageCommonDirectory() + "icon_arrow_right.gif"));
				grid.getRowFormatter().addStyleName(i+1, "Selected");
			}
			else {
				grid.setWidget(i+1, 4, new Image(getImageCommonDirectory() + "icon_info.gif"));
				grid.getRowFormatter().removeStyleName(i+1, "Selected");
			}
		}
		bodyPanel.add(grid);
		if (sz > 0 && selectedModuleModel != null)
		{
			subcomponent = new ConfigurationSubComponent(
					selectedModuleModel, adminController, getHandle(), subComponentCallback);
			subcomponent.build();
			bodyPanel.add(subcomponent);
		}
		clear();
		add(bodyPanel);


		onBuilt();
	}

	public void setSelectedGroup(String selectedGroup) {
		this.selectedGroup = selectedGroup;
	}
	public ModuleModel getSelectedModuleModel() {
		return selectedModuleModel;
	}
	public void setSelectedModuleModel(ModuleModel selectedModuleModel) {
		this.selectedModuleModel = selectedModuleModel;
	}

	protected ClickHandler tableHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			HTMLTable.Cell cell = grid.getCellForEvent(event);
			int rowIndex = cell.getRowIndex();
			if (rowIndex > 0)
			{
				ModuleModel moduleModel = moduleModels.get(rowIndex -1);
				selectedModuleModel = moduleModel;
				int sz = moduleModels.size();
				for (int i = 0; i < sz; i++)
				{
					moduleModel = moduleModels.get(i);
					if (selectedModuleModel == moduleModel) {
						grid.setWidget(i+1, 4, new Image(getImageCommonDirectory() + "icon_arrow_right.gif"));
						grid.getRowFormatter().addStyleName(i+1, "Selected");
					}
					else {
						grid.setWidget(i+1, 4, new Image(getImageCommonDirectory() + "icon_info.gif"));
						grid.getRowFormatter().removeStyleName(i+1, "Selected");
					}
				}
				bodyPanel.remove(subcomponent);
				subcomponent = new ConfigurationSubComponent(
						selectedModuleModel, adminController, getHandle(), subComponentCallback);
				subcomponent.build();
				bodyPanel.add(subcomponent);
			}
		}
	};

	protected SubComponentCallback subComponentCallback = 
		new SubComponentCallback() {

		public void onNavigate(CommonSubComponent subComponent) {
		}

		public void onSuccess(CommonSubComponent subComponent) {
			ConfigurationSubComponent configurationSubComponent = (ConfigurationSubComponent)subComponent;
			action = configurationSubComponent.getAction();
			build(true);
		}

		public void onError(CommonSubComponent subComponent, Throwable exception) {}
	};

	public boolean updateFromHistoryParameters(String[] params)
	{
		if (params.length > 1)
		{
			int id = Integer.parseInt(params[1]);
			setVisible(true);
			ModuleGroupComponent moduleGroupComponent = (ModuleGroupComponent)controller.getComponent("ModuleGroupComponent");
			moduleGroupComponent.setSelectedGroupModel(id);
			moduleGroupComponent.setSelectedInGUI();
			adminController.getNavigationStackPanel().showStack(moduleGroupComponent.getIndex());
			GroupModel groupModel = moduleGroupComponent.getSelectedGroupModel();
			setSelectedGroup(groupModel.getGroup());
		}
		return super.updateFromHistoryParameters(params);
	}
}
